www.gusucode.com > VC++ ASP文件上传组件源代码+调用示例-源码程序 > VC++ ASP文件上传组件源代码+调用示例-源码程序/code/aspup_src/MyRequest/Form.cpp
//Download by http://www.NewXing.com // Form.cpp : Implementation of CForm #include "stdafx.h" #include "MyRequest.h" #include "Parser.h" #include "Form.h" #include <string> using namespace std; ///////////////////////////////////////////////////////////////////////////// // CForm CForm::CForm() { m_bOnStartPageCalled = FALSE; } ///////////////////////////////////////////////////////////////////////////// // ISupportsErrorInfo interface implementation STDMETHODIMP CForm::InterfaceSupportsErrorInfo(REFIID riid) { static const IID* arr[] = { &IID_IForm }; for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++) { if (InlineIsEqualGUID(*arr[i],riid)) return S_OK; } return S_FALSE; } ///////////////////////////////////////////////////////////////////////////// // IForm interface implementation STDMETHODIMP CForm::OnStartPage(IUnknown* pUnk) { if(!pUnk) return E_POINTER; CComQIPtr<IScriptingContext, &IID_IScriptingContext> spContext(pUnk); if(!spContext) return E_NOINTERFACE; // Get Request Object Pointer HRESULT hr = spContext->get_Request(&m_piRequest); if(FAILED(hr)) return hr; // Get Response Object Pointer hr = spContext->get_Response(&m_piResponse); if(FAILED(hr)) return hr; m_bOnStartPageCalled = TRUE; return S_OK; } STDMETHODIMP CForm::OnEndPage() { m_bOnStartPageCalled = FALSE; m_piRequest.Release(); m_piResponse.Release(); return S_OK; } STDMETHODIMP CForm::Init(VARIANT varBinary) { CComVariant vtBinary = varBinary; HRESULT hr = S_OK; // ** if varBinary is not been supplied if(vtBinary.vt == VT_ERROR) { if(m_piRequest == NULL) return ::Error(_T("Form.Init()"), _T("Object has not initialized correctly"), IID_IForm, E_POINTER); long lSize; m_piRequest->get_TotalBytes(&lSize); CComVariant vtSize = lSize; // ** read from ASP Request Object m_piRequest->BinaryRead(&vtSize, &vtBinary); } BOOL bValid = GetRequestMethod() == _T("POST"); if(!bValid) return ::Error(_T("Form.Init()"), _T("method must be set to 'POST'"), IID_IForm); bValid = GetContentType() == _T("multipart/form-data"); if(!bValid) return ::Error(_T("Form.Init()"), _T("encoding type must be set to 'multipart/form-data'"), IID_IForm); // ** Should be safe array containing variants if(vtBinary.vt != (VT_UI1|VT_ARRAY)) return ::Error(_T("Form.Init()"), _T("Input type was not expected"), IID_IForm); SAFEARRAY* pSafeArray = (SAFEARRAY*)(vtBinary.pparray); CComBSTR bstr = GetBoundry(); int cbMultiByte = ::WideCharToMultiByte(CP_ACP, 0, bstr, -1, NULL, 0, NULL, NULL); LPSTR lpMultiByteStr = new char[cbMultiByte+2]; ::WideCharToMultiByte(CP_ACP, 0, bstr, -1, lpMultiByteStr, cbMultiByte, NULL, NULL); CBuffer bBoundry(lpMultiByteStr); // ** Get a pointer to the elements of the array. LPBYTE HUGEP lpData; SafeArrayAccessData(pSafeArray, (void HUGEP* FAR*)&lpData); long lLBound, lUBound; // ** One dimensional array. Get the bounds for the array. SafeArrayGetLBound(pSafeArray, 1, &lLBound); SafeArrayGetUBound(pSafeArray, 1, &lUBound); // ** Get the count of elements long lDataSize = lUBound-lLBound + 1; CBuffer bRequest(lpData, lDataSize); CParser p(bRequest, bBoundry); hr = p.Parse(this); if(FAILED(hr)) return ::Error(_T("Form.Init()"), _T("object has encountered an error during parsing"), IID_IForm, hr); delete[] lpMultiByteStr; // ** Decrement the access count for the array. SafeArrayUnaccessData(pSafeArray); return S_OK; } STDMETHODIMP CForm::get_Count(long* plCount) { if(plCount == NULL) return E_POINTER; *plCount = m_vecItems.size(); return S_OK; } STDMETHODIMP CForm::get_Item(VARIANT Index, IListItem** ppItem) { if(ppItem == NULL) return E_POINTER; if(Index.vt != VT_BSTR) { CComVariant vtIndex(Index); HRESULT hr = vtIndex.ChangeType(VT_I4); if(FAILED(hr)) return ::Error(_T("Form.Item()"), _T("input type is not expected"), IID_IForm, hr); long lIndex = vtIndex.lVal; if(lIndex < 1 || lIndex > m_vecItems.size()) return ::Error(_T("Form.Item()"), _T("index is out of range"), IID_IForm, E_INVALIDARG); // ** Get the item CComObject<CListItem>* pListItem = m_vecItems[lIndex-1]; hr = pListItem->QueryInterface(IID_IListItem, (void **)ppItem); if(FAILED(hr)) return E_UNEXPECTED; return S_OK; } CComBSTR bstrName = Index.bstrVal; bstrName.ToLower(); for(int i = 0; i < m_vecItems.size(); i++) { CComObject<CListItem>* pListItem = m_vecItems[i]; CComBSTR bstrItemName = pListItem->GetName(); bstrItemName.ToLower(); if(bstrName == bstrItemName) { HRESULT hr = pListItem->QueryInterface(IID_IListItem, (void **)ppItem); if(FAILED(hr)) return E_UNEXPECTED; return S_OK; } } return ::Error(_T("Form.Item()"), _T("index key is not valid"), IID_IForm, E_INVALIDARG); } STDMETHODIMP CForm::get__NewEnum(IUnknown** ppUnk) { if(ppUnk == NULL) return E_POINTER; typedef CComEnum<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT> > ComVarEnum; typedef CComObject<ComVarEnum> VariantEnum; VariantEnum* pEnum = NULL; HRESULT hr = VariantEnum::CreateInstance(&pEnum); if(FAILED(hr)) return hr; std::vector< CComVariant > vecItems; for(int i = 0; i < m_vecItems.size(); i++) { // ** Get the item CComObject<CListItem>* pItem = m_vecItems[i]; IDispatch* pDispatch; pItem->QueryInterface(IID_IDispatch, (void **)&pDispatch); vecItems.push_back(CComVariant(pDispatch)); pDispatch->Release(); } hr = pEnum->Init(vecItems.begin(), vecItems.end(), 0, AtlFlagCopy); if(FAILED(hr)) return hr; hr = pEnum->QueryInterface(IID_IEnumVARIANT, (void**) ppUnk); if(FAILED(hr)) return hr; return S_OK; } CComObject<CListItem>* CForm::GetItem(const CComBSTR& bstrName) { CComBSTR bstrTemp = bstrName; bstrTemp.ToLower(); CComObject<CListItem>* pListItem = NULL; for(int i = 0; i < m_vecItems.size(); i++) { pListItem = m_vecItems[i]; CComBSTR bstrItemName = pListItem->GetName(); bstrItemName.ToLower(); if(bstrTemp == bstrItemName) { return pListItem; } } return NULL; } void CForm::AddItem(CComBSTR bstrName, CComBSTR bstrFileName, CComBSTR bstrCType, CBuffer bContent, BOOL bFile) { CComObject<CListItem>* pListItem = GetItem(bstrName); if(pListItem == NULL) { HRESULT hr = CComObject<CListItem>::CreateInstance(&pListItem); pListItem->AddRef(); pListItem->SetName(bstrName); m_vecItems.push_back(pListItem); } pListItem->AddItem(bstrFileName, bstrCType, bContent, bFile); } void CForm::FinalRelease() { m_vecItems.erase(m_vecItems.begin(), m_vecItems.end()); } CComBSTR CForm::GetRequestMethod() { CComPtr<IRequestDictionary> piServerVariables; m_piRequest->get_ServerVariables(&piServerVariables); IRequestDictionary* pServerVariablesDictionary; m_piRequest->get_ServerVariables(&pServerVariablesDictionary); CComVariant vtItemName(_T("REQUEST_METHOD")); CComVariant vtRequestMethod; piServerVariables->get_Item(vtItemName, &vtRequestMethod); vtRequestMethod.ChangeType(VT_BSTR); CComBSTR bstrRequestMethod = vtRequestMethod.bstrVal; bstrRequestMethod.ToUpper(); return bstrRequestMethod; } CComBSTR CForm::GetContentType() { CComPtr<IRequestDictionary> piServerVariables; m_piRequest->get_ServerVariables(&piServerVariables); CComVariant vtItemName(_T("HTTP_CONTENT_TYPE")); CComVariant vtContentType; piServerVariables->get_Item(vtItemName, &vtContentType); vtContentType.ChangeType(VT_BSTR); CComBSTR bstrTemp(vtContentType.bstrVal); bstrTemp.ToLower(); wstring wstr = bstrTemp; int i = wstr.find(L"multipart/form-data;"); if(i == -1) return _T(""); else return _T("multipart/form-data"); } CComBSTR CForm::GetBoundry() { CComPtr<IRequestDictionary> piServerVariables; m_piRequest->get_ServerVariables(&piServerVariables); CComVariant vtItemName(_T("HTTP_CONTENT_TYPE")); CComVariant vtContentType; piServerVariables->get_Item(vtItemName, &vtContentType); vtContentType.ChangeType(VT_BSTR); CComBSTR bstrTemp(vtContentType.bstrVal); bstrTemp.ToLower(); wstring wstr = bstrTemp; int i = wstr.find(L"boundary="); if(i == -1) return _T(""); wstring wstrResult = wstr.substr(i+9); CComBSTR bstr(wstrResult.c_str()); return bstr; }